import queue
import random
import threading
import time
from PySide6.QtCore import QObject, Signal, QThread

import constants
import numpy

from Alarm.alarm import Alarm
from constants import *
import os
from loguru import logger

length_queue = 100

random_list_ratio = ["1:1","1:2", "1:3", "1:4", "1:5", "1:6"]
random_list_speed = ["1m/s", "2m/s", "3m/s", "4m/s", "5m/s", "6m/s"]


class BackendWorker(QObject):
    # 定义发送到主线程的信号
    toMainThreadSignal = Signal(dict)

    def __init__(self):
        super().__init__()
        self.alarm = Alarm("Alarm/alarm.wav")
        self.alarm_isopen = False
        self.alarm_ismute = False
        self.mutetime = 0

    def processMainThreadMessage(self, message):
        # 模型处理后返回给主线程
        if "image" in message:
            if isinstance(message["image"], numpy.ndarray):
                view = message["index"]
                self.toMainThreadSignal.emit(
                    ({"ratio": random_list_ratio[random.randint(0, 5)] , "speed":random_list_speed[random.randint(0, 5)]})
                )
        else:
            logger.info(f"Worker received message from main thread: {message}")
            type = message["type"]
            if type == Constants.TYPE_MUTE:
                # {"type": Constants.TYPE_MUTE, "mutetime": 30}
                if self.alarm_ismute == False:
                    self.alarm_ismute = not self.alarm_ismute
                    mutetime = message["mutetime"]
                    self.alarm_isopen = False
                    self.alarm.stop_alarm()
                    self.mutetime = mutetime
                    logger.info(f"开启静音{self.mutetime}s")
                    thread = threading.Thread(target=self.muteTime)
                    thread.daemon = True
                    thread.start()
                else:
                    logger.info(f"关闭静音")
                    self.alarm_ismute = not self.alarm_ismute
                    self.mutetime = 0

            elif type == Constants.TYPE_ALARM:
                # {"type": Constants.TYPE_ALARM, 'alarmtime' : 10}
                if self.mutetime > 0:
                    logger.info(f"报警器已被静音, 还剩余{self.mutetime}s")
                else:
                    if self.alarm_isopen == True and self.mutetime == 0:
                        logger.info(f"关闭报警")
                        self.alarm_isopen = not self.alarm_isopen
                        self.alarm.stop_alarm()
                    elif self.alarm_isopen == False and self.mutetime == 0:
                        logger.info(f"开启报警")
                        self.alarm_isopen = not self.alarm_isopen
                        self.alarmOpen(message["alarmtime"])

            elif type == Constants.TYPE_EXCEPTION:
                pass

            elif type == Constants.TYPE_LOG:
                pass
                # self.log_window.show()

    def multiprocessImage(self):
        for view in range(0, 2):
            thread = threading.Thread(target=self.processingImage, args=(self.images[view], view, self.models[view], self.results))
            thread.daemon = True
            thread.start()

    def processingImage(self, image_queue, view, model, result_queue):
        # label = ['zhedang', 'shila', 'ruye', 'no_work']
        label = ['0', '1', '2', '3']
        model1, generator1, soft_value1 = model
        queue_product_consume = result_queue[view]
        queue_product_consume_2 = result_queue[(view + 1) % 2]

        count = self.count_arr[view][4]  # 队列中已有数字的总数量
        count_0 = self.count_arr[view][0]  #
        count_1 = self.count_arr[view][1]   # 队列中数字 '1' 的数量
        count_2 = self.count_arr[view][2]  # 队列中数字 '2' 的数量
        count_3 =  self.count_arr[view][3]  # 队列中数字 ‘3’ 的数量

        count_other = self.count_arr[(view + 1) % 2][4]  # 队列中已有数字的总数量
        count_0_other = self.count_arr[(view + 1) % 2][0]  #
        count_1_other= self.count_arr[(view + 1) % 2][1]   # 队列中数字 '1' 的数量
        count_2_other = self.count_arr[(view + 1) % 2][2]  # 队列中数字 '2' 的数量
        count_3_other =  self.count_arr[(view + 1) % 2][3]  # 队列中数字 ‘3’ 的数量


        while True:
            if image_queue.empty():
                continue
            img = image_queue.get()
            img = transform_img(img)
            output = get_pred(img, model1, generator1, soft_value1)
            del img
            result = label[torch.argmax(output[0])]

            if not queue_product_consume.full():  # 如果队列未满
                queue_product_consume.put(result)  # 将结果放入队列
                count += 1  # 更新总数量计数
                if result == '0':
                    count_0 += 1
                elif result == '1':  # 如果结果为 '1'
                    count_1 += 1  # 更新 '1' 的数量计数
                elif result == '2':  # 如果结果为 '2'
                    count_2 += 1  # 更新 '2' 的数量计数
                elif result == '3':
                    count_3 += 1

                # 检查条件1：队列中数字为 '2' 的比例达到了总队列已有数字总量的 90%
                if count_2 / count >= 0.8 and count > 30:
                # if (count_2 / count >= 0.8 and count > 30) or (count_2_other / count_other >= 0.8 and count_other > 30):
                    if CurrentState.status[view] != ParaffinStatus.LATEX:  # 乳液
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.LATEX})
                        )
                        # self.alarmOpen()

                # 检查条件2：队列中数字为 '1' 的比例达到了总队列已有数字总量的 90%
                elif count_0 / count >= 0.8 and count > 30:
                # elif (count_0 / count >= 0.8 and count > 30) or (count_0_other / count_other >= 0.8 and count_other > 30):
                    if CurrentState.status[view] != ParaffinStatus.OCCLUSION:
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.OCCLUSION})
                        )
                        # self.alarmOpen()
                elif count_1 / count >= 0.8 and count > 30:
                # elif (count_2 / count >= 0.8 and count > 30) or (count_2_other / count_other >= 0.8 and count_other > 30):
                    if CurrentState.status[view] != ParaffinStatus.NORMAL:
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.NORMAL})
                        )
                else:
                    if CurrentState.status[view] != ParaffinStatus.FREE:
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.FREE})
                        )

            else:  # 如果队列已满
                removed = queue_product_consume.get()  # 移除队列中最早放入的结果
                count -= 1  # 更新总数量计数
                if removed == '1':  # 如果移除的结果为 '1'
                    count_1 -= 1  # 更新 '1' 的数量计数
                elif removed == '2':  # 如果移除的结果为 '2'
                    count_2 -= 1  # 更新 '2' 的数量计数

                queue_product_consume.put(result)  # 将新结果放入队列
                count += 1  # 更新总数量计数
                if result == '0':
                    count_0 += 1
                elif result == '1':  # 如果结果为 '1'
                    count_1 += 1  # 更新 '1' 的数量计数
                elif result == '2':  # 如果结果为 '2'
                    count_2 += 1  # 更新 '2' 的数量计数
                elif result == '3':
                    count_3 += 1

                # 检查条件1：队列中数字为 '2' 的比例达到了总队列已有数字总量的 90%
                if count_2 / count >= 0.8:
                    if CurrentState.status[view] != ParaffinStatus.LATEX:  # 乳液
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.LATEX})
                        )
                        # self.alarmOpen()

                # 检查条件2：队列中数字为 '1' 的比例达到了总队列已有数字总量的 90%
                elif count_0 / count >= 0.8:
                    if CurrentState.status[view] != ParaffinStatus.OCCLUSION:
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.OCCLUSION})
                        )
                        # self.alarmOpen()
                elif count_1 / count >= 0.8:
                    if CurrentState.status[view] != ParaffinStatus.NORMAL:
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.NORMAL})
                        )
                else:
                    if CurrentState.status[view] != ParaffinStatus.FREE:
                        self.toMainThreadSignal.emit(
                            ({"type": Constants.TYPE_STATUS, "view": view, "state": ParaffinStatus.FREE})
                        )

    def muteTime(self):
        while (self.mutetime > 0):
            self.mutetime -= 1
            time.sleep(1)

    def alarmOpen(self, alarmtime=10):
        thread = threading.Thread(target=AlarmController, args=(self.alarm, alarmtime))
        thread.daemon = True
        thread.start()